home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Business & Presentations
/
Business and Presentations - Volume 1 (1995)(Sideface)(NL).iso
/
gfxapps
/
dos
/
viewfont
/
putbits.asm
next >
Wrap
Assembly Source File
|
1989-08-24
|
4KB
|
176 lines
; putbits() - by Mike Salisbury - August 25, 1989
;
; call from C as: putbits(x,y,width,height,bufferptr,fgcolor)
; x : x position
; y : y position
; width : character width in bits
; height : character height in bits
; bufferptr : pointer to byte buffer holding character
; fgcolor : foreground color of character (bg stays same)
;
; putbits will draw a laserjet formatted character to an ega screen.
; x does not have to be byte aligned, but I have included an optimized
; routine for drawing byte aligned characters. I have only tested
; this on an EGA, but I believe it should work in VGA mode as well.
; This is a Turbo Assembler module. I really only save the registers
; I have to (CS,SS,DS,BP,SI,DI).
;
.model small,C
.code
PUBLIC putbits
putbits PROC
ARG x:WORD,y:WORD,w:WORD,h:WORD,buf:PTR WORD,color:BYTE
LOCAL endinc:WORD,count:WORD,color_shift:WORD,startmask:BYTE,endmask:BYTE
LOCAL shorter:BYTE
USES si,di
mov ax,0a000h
mov es,ax ; Set up EGA video segment
mov dx,w
dec dx
mov cl,3
shr dx,cl
inc dx
mov count,dx ; Save byte size width (rounded up from pixels)
mov ax,80
sub ax,dx ; ax = end of line increment
mov endinc,ax
mov ax,y
mov dx,80
mul dx
mov dx,x
mov cl,3
shr dx,cl ; Save byte size x offset
add ax,dx
mov di,ax ; di = video offset
mov cx,h
jcxz pbab1
mov si,buf ; si = character data pointer
mov dx,03ceh ; dx = video port
mov ax,0a05h ; set Read mode 1, write mode 2
out dx,ax
mov ax,0007h ; Set color don't care for all planes
out dx,ax
mov ax,x
and ax,7 ; check if byte aligned
jnz shifted
mov bl,color
mov al,8 ; al = Bit Mask register
pb1:
push cx
mov cx,count
pb2:
mov ah,[si] ; Byte Aligned
out dx,ax
and es:[di],bl ; Draw foreground
inc si
inc di
loop pb2
pop cx
add di,endinc
loop pb1
jmp pbexit
pbab1:
jmp pbabort ; stepping stone to exit for jcxz above
shifted:
mov ah,00
mov shorter,ah ; initialize shorter flag
mov cx,w ; si,di, and dx already set upon entry
dec cx
and cx,7
xor cl,7
mov ah,0ffh
shl ah,cl ; ah = original end mask
mov cl,al
xor cl,7
inc cl ; cl = bits to shift
mov ch,color
mov color_shift,cx ; save color and shift
mov al,ah
cbw ; ax = original end mask
mov bx,00ffh ; bx = original start mask
shl ax,cl
shl bx,cl ; shift both start and end masks
mov startmask,bh
dec endinc
or al,al
jnz pb3
dec count ; decrement total byte count
inc endinc
mov al,01
mov shorter,al ; shifted bytes fit in same space flag
mov al,ah
pb3:
mov endmask,al ; both start and end mask are now set
mov bx,count
or bx,bx
jnz pb4
and al,startmask
mov startmask,al ; if only one byte, combine masks
pb4:
mov cx,h
pbrept:
push cx
mov cx,color_shift
mov bx,count
lodsw ; AL = first byte, AH = second byte
dec si ; point back to second
rol ax,cl ; AH = cond+fi, AL = rst+sec
and ah,startmask
pb5:
mov al,8 ; bit mask register
out dx,ax
and es:[di],ch ; write bits
inc di
cmp bx,1
jle pb6
dec si
dec bx
lodsw
rol ax,cl
mov ah,al
jmp short pb5 ; go do next byte
pb6:
or bx,bx
jz pb7 ; if only one byte to start with, do next
dec si
lodsw
rol ax,cl
mov bl,shorter
or bl,bl
jnz pb8 ; if shorter flag not set, decrement buffer ptr
dec si
pb8:
mov ah,al
and ah,endmask
mov al,8
out dx,ax ; write ending byte
and es:[di],ch
inc di
pb7:
add di,endinc
pop cx
loop pbrept ; repeat for all lines
pbexit:
mov ax,0005h ; Reset read/write mode
out dx,ax
mov ax,0ff08h ; Reset Bit mask
out dx,ax
mov ax,00f07h ; Reset color don't care for all planes
out dx,ax
pbabort:
ret
putbits ENDP
END